import * as React from 'react';
import { connect } from 'react-redux';
import { Tabs, Icon, message } from 'antd';
import { upperFirst, camelCase } from 'lodash';

import TestParserPlugins from 'components/test-parser/index';

import { fetchTestDetail, fetchTestTplList } from 'actions/test';
import LoadableComponent from 'components/common/LoadableComponent';
const LoadableEditBasic = LoadableComponent(() => import('./EditBasic'));

// 模板描述可以修改变动
// 名称要与DB数据保持一致
// Ref与模板名称保持一致
const tpls = [
  {
    name: 'template1',
    ref: 'Tpl1',
  },
  {
    name: 'template2',
    ref: 'Tpl2',
  },
  {
    name: 'template3',
    ref: 'Tpl3',
  },
  {
    name: 'template4',
    ref: 'Tpl4',
  },
  {
    name: 'template5',
    ref: 'Tpl5',
  },
  {
    name: 'template6',
    ref: 'Tpl6',
  },
  {
    name: 'template7',
    ref: 'Tpl7',
  },
];
function getPluginRef(tplName: string) {
  const tpl = tpls.find((item: any) => {
    return item.name === tplName;
  });
  return tpl ? tpl.ref : '';
}

interface EditProps {
  dispatch: (action: any) => any;
  newTestCallback: (id: any) => any;
  lessonId: number;
  levelId: number;
  testId: any;
  editTest: any;
}

interface EditState {
  activeKey: string;
  tpls: any[];
}

class Edit extends React.Component<EditProps, EditState> {
  basicCounter: number;
  static defaultProps: EditProps = {
    dispatch: () => {},
    newTestCallback: () => {},
    editTest: null,
    testId: 0,
    levelId: 0,
    lessonId: 0,
  };
  constructor(props: EditProps) {
    super(props);
    this.state = {
      activeKey: 'basic',
      tpls: [],
    };
    this.basicCounter = 0;
  }

  componentWillMount() {
    if (this.props.testId) {
      this.handleFetchTestDetail();
    }
    this.props.dispatch(fetchTestTplList()).then((result: any) => {
      if (result.code) {
        message.error(result.msg);
      } else {
        this.setState({
          tpls: result.response.data.items,
        });
      }
    });
  }

  componentWillReceiveProps(nextProps: any) {
    const { testId } = nextProps;
    const { testId: oldTestId } = this.props;
    if (testId !== oldTestId) {
      if (testId) {
        this.handleFetchTestDetail(testId);
      }
      if (this.state.activeKey !== 'basic') {
        this.handleChangeTab('basic');
      }
    }
  }

  handleFetchTestDetail = (testId: number = this.props.testId) => {
    const { dispatch, lessonId } = this.props;
    dispatch(fetchTestDetail(lessonId, testId)).then((result: any) => {
      if (result.code) {
        message.error(result.msg);
      }
    });
  };

  handleChangeTab = (activeKey: string) => {
    this.setState({
      activeKey,
    });
  };

  render() {
    let TestParser = null;
    const plugins = TestParserPlugins;
    let { newTestCallback, levelId, lessonId, testId, editTest } = this.props;
    let { activeKey, tpls } = this.state;

    editTest = testId ? editTest : null;
    const isNewRecord = !editTest;

    if (typeof plugins === 'object') {
      try {
        let pluginName = '';
        if (editTest && tpls.length) {
          const tpl = tpls.find((item: any) => {
            return item.id === editTest.templateId;
          });
          if (tpl) {
            pluginName = getPluginRef(tpl.name);
          }
        }

        if (pluginName) {
          pluginName = upperFirst(camelCase(pluginName));
        }

        if (plugins[pluginName]) {
          TestParser = plugins[pluginName];
        } else {
          TestParser = plugins.Default;
        }
      } catch (e) {
        console.warn(e.message);

        TestParser = plugins.Default;
      }
    }

    return (
      <Tabs size="small" animated={false} onChange={this.handleChangeTab} activeKey={activeKey}>
        <Tabs.TabPane
          tab={
            <p>
              <Icon type={isNewRecord ? 'plus' : 'edit'} />
              {isNewRecord ? '新增' : '修改'}
              &nbsp;闯关测试
            </p>
          }
          key="basic">
          <LoadableEditBasic
            lessonId={lessonId}
            levelId={levelId}
            editTest={editTest}
            tpls={tpls}
            newTestCallback={newTestCallback}
            key={`basic_info_${this.basicCounter}`}
          />
        </Tabs.TabPane>
        <Tabs.TabPane
          tab={
            <p>
              <Icon type={isNewRecord ? 'lock' : 'code-o'} />
              闯关测试内容
            </p>
          }
          key="template"
          disabled={isNewRecord}>
          {activeKey === 'template' && (
            <TestParser
              levelId={levelId}
              lessonId={lessonId}
              testId={testId}
              fetchTestDetail={this.handleFetchTestDetail}
            />
          )}
        </Tabs.TabPane>
      </Tabs>
    );
  }
}

interface OwnProps {
  lessonId: number;
  levelId: number;
  testId: number;
}
function mapStateToProps(state: any, ownProps: OwnProps) {
  let { lessonId, levelId, testId } = ownProps;
  const { editTest } = state.test;

  return {
    lessonId,
    testId,
    levelId,
    editTest,
  };
}

export default connect(mapStateToProps)(Edit);
